package com.zhuanzhuan.hero.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bj58.youpin.common.utils.json.JsonUtils;
import com.bj58.zhuanzhuan.zzentry.common.service.entity.ServiceHeaderEntity;
import com.zhuanzhuan.hero.biz.common.entity.risk.control.request.UserContactRiskControlRequest;
import com.zhuanzhuan.hero.biz.common.entity.risk.control.response.RiskControlResult;
import com.zhuanzhuan.hero.biz.common.enums.RiskControlResultType;
import com.zhuanzhuan.hero.user.consts.Consts;
import com.zhuanzhuan.hero.user.consts.NumConsts;
import com.zhuanzhuan.hero.user.dto.UserContactDTO;
import com.zhuanzhuan.hero.user.entity.HeroUserContact;
import com.zhuanzhuan.hero.user.enums.ExceptionMsgEnum;
import com.zhuanzhuan.hero.user.enums.RiskControlFieldEnum;
import com.zhuanzhuan.hero.user.enums.StateEnum;
import com.zhuanzhuan.hero.user.exception.BusinessException;
import com.zhuanzhuan.hero.user.helper.PushHelper;
import com.zhuanzhuan.hero.user.mapper.HeroUserContactMapper;
import com.zhuanzhuan.hero.user.mq.dto.UserInfoUpdateMsg;
import com.zhuanzhuan.hero.user.mq.producer.HeroUserProducer;
import com.zhuanzhuan.hero.user.pojo.bo.QueryContactParam;
import com.zhuanzhuan.hero.user.service.HeroUserContactService;
import com.zhuanzhuan.hero.user.service.IPushService;
import com.zhuanzhuan.hero.user.service.IRiskControlService;
import com.zhuanzhuan.hero.user.service.IUserService;
import com.zhuanzhuan.hero.user.util.Assert;
import com.zhuanzhuan.hero.user.util.StringUtil;
import com.zhuanzhuan.hero.user.vo.UserStoreVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * dal Interface:HeroUserContact
 * @author hanjunjun
 * @date 2024-6-17
 */
@Service
@Slf4j
public class HeroUserContactServiceImpl extends ServiceImpl<HeroUserContactMapper, HeroUserContact> implements
    HeroUserContactService {

    @Autowired
    private HeroUserContactMapper userContactMapper;

    @Resource
    private IRiskControlService riskControlService;

    @Resource
    private IPushService pushService;

    @Resource
    private IUserService userService;

    @Resource
    private HeroUserProducer heroUserProducer;

    @Override
    public Long registInitUserContactInfo(Long uid, String mobile, String nickname, String profilePhoto) {
        HeroUserContact heroUserContact = new HeroUserContact();
        heroUserContact.setUid(uid)
            .setContactMobile(mobile)
            .setIsPublicContact(NumConsts.ONE)
            .setIsRequireAttention(NumConsts.ONE)
            .setState(StateEnum.EFFECTIVE.getCode())
            .setCreateBy(NumConsts.SYSTEM_CODE)
            .setUpdateBy(NumConsts.SYSTEM_CODE);
        return this.createHeroUserContact(heroUserContact);
    }

    @Override
    public UserContactDTO queryUserContactByUid(Long uid) {
        HeroUserContact userContact = this.getByUid(uid);
        if (Objects.isNull(userContact)) {
            log.error("userContact不存在");
            throw new BusinessException(ExceptionMsgEnum.BUSINESS_ERROR);
        }

        return this.convertUserContactVO(userContact);
    }

    @Override
    public List<HeroUserContact> listByParam(QueryContactParam param) {
        HeroUserContact query = new HeroUserContact();
        query.setContactMobile(param.getContactMobile());
        query.setState(StateEnum.EFFECTIVE.getCode());
        return this.getBaseMapper().select(query);
    }

    @Override
    public void updateUserContact(long uid, UserContactDTO userContactDTO, ServiceHeaderEntity header) {
        //查原来的
        HeroUserContact dbRecord = this.getByUid(uid);
        Assert.notNull(dbRecord, ExceptionMsgEnum.DATA_NOT_EXIST);

        HeroUserContact updateRecord = new HeroUserContact();

        //对比判断是否需要风控
        UserContactRiskControlRequest riskControlRequest = new UserContactRiskControlRequest();
        boolean needRiskControl = this.buildRiskControlRequestAndUpdateRecord(riskControlRequest, userContactDTO,
            updateRecord, dbRecord);
        if (needRiskControl) {
            RiskControlResult riskControlResult =
                riskControlService.userContactInfoRiskControl(uid, header, riskControlRequest);
            if (RiskControlResultType.PASS.getCode() != riskControlResult.getResult()) {
                log.info("用户修改联系方式风控不通过");
                throw new BusinessException(ExceptionMsgEnum.BUSINESS_ERROR.getCode(), Consts.RISK_CONTROL_FAIL_TPS);
            }
        }

        //保存
        updateRecord.setId(dbRecord.getId()).setCreateBy(uid).setUpdateBy(uid);
        userContactMapper.updateByPrimaryKey(updateRecord);

        boolean sendResult = heroUserProducer.sendContactInfoUpdate(
            new UserInfoUpdateMsg(uid, ""));
        if (!sendResult) {
            log.info("修改联系方式同步search失败 uid={}", uid);
        }

        //个人信息是否完善 完善则发送mq
        userService.personInfoPerfectionBroadcast(uid);
    }

    @Override
    public UserStoreVO queryUserStore(Long targetUid) {
        HeroUserContact heroUserContact = this.getByUid(targetUid);
        Assert.notNull(heroUserContact, ExceptionMsgEnum.DATA_NOT_EXIST);

        return this.convertUserStoreVO(heroUserContact);
    }

    @Override
    public boolean riskcontrolFail(Long uid, List<String> rejectFields) {
        log.info("个人联系方式风控失败,uid={} rejectFields={}", uid, JsonUtils.toJsonWithoutNull(rejectFields));

        //push模板要替换的值
        LambdaUpdateWrapper<HeroUserContact> updateWrapper = new LambdaUpdateWrapper<>();

        if (rejectFields.contains(RiskControlFieldEnum.CONTACT_MOBILE.getField())) {
            log.info("联系手机号风控失败，清空");
            updateWrapper.set(HeroUserContact::getContactMobile, "");
        }
        if (rejectFields.contains(RiskControlFieldEnum.WECHAT_NO.getField())) {
            log.info("微信号风控失败，清空");
            updateWrapper.set(HeroUserContact::getWechatNum, "");
        }
        if (rejectFields.contains(RiskControlFieldEnum.DOUYIN_NICKNAME.getField())) {
            log.info("抖音昵称风控失败，清空");
            updateWrapper.set(HeroUserContact::getDouyinNickname, "");
        }
        if (rejectFields.contains(RiskControlFieldEnum.STORE_NAME.getField())) {
            log.info("店铺名称风控失败，清空");
            updateWrapper.set(HeroUserContact::getStoreName, "");
        }
        if (rejectFields.contains(RiskControlFieldEnum.STORE_ADDRESS.getField())) {
            log.info("店铺地址风控失败，清空");
            updateWrapper.set(HeroUserContact::getStoreAddress, "");
        }
        if (rejectFields.contains(RiskControlFieldEnum.WECHAT_GROUP_NAME.getField())) {
            log.info("微信群名称风控失败，清空");
            updateWrapper.set(HeroUserContact::getWechatGroupName, "");
        }
        if (rejectFields.contains(RiskControlFieldEnum.WECHAT_GROUP_INTRODUCTION.getField())) {
            log.info("微信群简介风控失败，清空");
            updateWrapper.set(HeroUserContact::getWechatGroupDesc, "");
        }
        if (rejectFields.contains(RiskControlFieldEnum.WECHAT_GROUP_CODE.getField())) {
            log.info("微信群二维码风控失败，清空");
            //删除微信群二维码
            updateWrapper.set(HeroUserContact::getWechatGroupCode, "");
        }
        if (rejectFields.contains(RiskControlFieldEnum.STORE_PHOTOS.getField())) {
            //删除店铺实拍
            updateWrapper.set(HeroUserContact::getStorePhotos, "");
        }

        updateWrapper.set(HeroUserContact::getUpdateBy, NumConsts.SYSTEM_CODE)
            .eq(HeroUserContact::getUid, uid).eq(HeroUserContact::getState, StateEnum.EFFECTIVE.getCode());
        this.update(updateWrapper);

        //发送push
        if (CollectionUtils.isNotEmpty(rejectFields)) {
            rejectFields.forEach(rejectField -> {
                String rejectTitle = riskControlService.parseTitleByField(rejectField);
                pushService.sendPushAsync(uid, PushHelper.CONTACT_INFO_TEMPLATE_ID,
                    PushHelper.parseParamMapByField(rejectTitle));
            });
        }

        return true;
    }

    @Override
    public HeroUserContact getByUid(Long uid) {
        HeroUserContact query = new HeroUserContact();
        query.setUid(uid);
        query.setState(StateEnum.EFFECTIVE.getCode());
        List<HeroUserContact> list = userContactMapper.select(query);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return list.get(0);
    }

    @Override
    public List<HeroUserContact> listByUid(List<Long> uids) {
        LambdaQueryWrapper<HeroUserContact> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(HeroUserContact::getUid, uids)
            .eq(HeroUserContact::getState, StateEnum.EFFECTIVE.getCode());

        return this.list(queryWrapper);
    }

    @Override
    public boolean delByUid(Long uid) {
        LambdaUpdateWrapper<HeroUserContact> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(HeroUserContact::getState, StateEnum.IS_DELETED.getCode())
            .eq(HeroUserContact::getUid, uid)
            .eq(HeroUserContact::getState, StateEnum.EFFECTIVE.getCode());

        return this.update(updateWrapper);
    }

    private UserContactDTO convertUserContactVO(HeroUserContact userContact) {
        UserContactDTO vo = new UserContactDTO();
        vo.setMobilePhone(userContact.getContactMobile())
            .setWechatNum(userContact.getWechatNum())
            .setWechatGroupCode(userContact.getWechatGroupCode())
            .setWechatGroupName(userContact.getWechatGroupName())
            .setWechatGroupDesc(userContact.getWechatGroupDesc())
            .setDouyinNickname(userContact.getDouyinNickname())
            .setIsPublicContact(userContact.getIsPublicContact())
            .setIsRequireAttention(userContact.getIsRequireAttention());

        UserStoreVO storeInfo = new UserStoreVO();
        storeInfo.setStoreName(userContact.getStoreName())
            .setStorePhotos(StringUtil.str2List(userContact.getStorePhotos()))
            .setProvinceId(userContact.getStoreProvinceId())
            .setProvinceName(userContact.getStoreProvince())
            .setCityId(userContact.getStoreCityId())
            .setCityName(userContact.getStoreCity())
            .setCountryId(userContact.getStoreCountryId())
            .setCountryName(userContact.getStoreCountry())
            .setAddress(userContact.getStoreAddress());
        vo.setStoreInfo(storeInfo);

        return vo;
    }

    private boolean buildRiskControlRequestAndUpdateRecord(UserContactRiskControlRequest riskControlRequest,
        UserContactDTO userContactDTO, HeroUserContact updateRecord, HeroUserContact dbRecord) {
        boolean needRiskControl = false;
        if (!Objects.equals(dbRecord.getContactMobile(), userContactDTO.getMobilePhone())) {
            if (StringUtils.isNotBlank(userContactDTO.getMobilePhone())) {
                needRiskControl = true;
                riskControlRequest.setMobile(userContactDTO.getMobilePhone());
            }
            updateRecord.setContactMobile(userContactDTO.getMobilePhone());
        }
        if (!Objects.equals(dbRecord.getWechatNum(), userContactDTO.getWechatNum())) {
            if (StringUtils.isNotBlank(userContactDTO.getWechatNum())) {
                needRiskControl = true;
                riskControlRequest.setWechatNo(userContactDTO.getWechatNum());
            }
            updateRecord.setWechatNum(userContactDTO.getWechatNum());
        }
        if (!Objects.equals(dbRecord.getDouyinNickname(), userContactDTO.getDouyinNickname())) {
            if (StringUtils.isNotBlank(userContactDTO.getDouyinNickname())) {
                needRiskControl = true;
                riskControlRequest.setDouyinNickname(userContactDTO.getDouyinNickname());
            }
            updateRecord.setDouyinNickname(StringUtil.getOrEmpty(userContactDTO.getDouyinNickname()));
        }
        if (!Objects.equals(dbRecord.getWechatGroupCode(), userContactDTO.getWechatGroupCode())) {
            if (StringUtils.isNotBlank(updateRecord.getWechatGroupCode())) {
                needRiskControl = true;
                riskControlRequest.setWechatGroupPicture(updateRecord.getWechatGroupCode());
            }
            //如果为null就赋值"" 使得mapper进行更新
            updateRecord.setWechatGroupCode(StringUtil.getOrEmpty(userContactDTO.getWechatGroupCode()));
        }
        if (!Objects.equals(dbRecord.getWechatGroupName(), userContactDTO.getWechatGroupName())) {
            if (StringUtils.isNotBlank(userContactDTO.getWechatGroupName())) {
                needRiskControl = true;
                riskControlRequest.setWechatGroupName(userContactDTO.getWechatGroupName());
            }
            updateRecord.setWechatGroupName(StringUtil.getOrEmpty(userContactDTO.getWechatGroupName()));
        }
        if (!Objects.equals(dbRecord.getWechatGroupDesc(), userContactDTO.getWechatGroupDesc())) {
            if (StringUtils.isNotBlank(userContactDTO.getWechatGroupDesc())) {
                needRiskControl = true;
                riskControlRequest.setWechatGroupIntroduction(userContactDTO.getWechatGroupDesc());
            }
            updateRecord.setWechatGroupDesc(StringUtil.getOrEmpty(userContactDTO.getWechatGroupDesc()));
        }
        UserStoreVO storeInfo = userContactDTO.getStoreInfo();
        if (!Objects.equals(dbRecord.getStoreName(), storeInfo.getStoreName())) {
            if (StringUtils.isNotBlank(updateRecord.getStoreName())) {
                needRiskControl = true;
                riskControlRequest.setShopName(updateRecord.getStoreName());
            }
            updateRecord.setStoreName(storeInfo.getStoreName());
        }
        if (!Objects.equals(dbRecord.getStoreAddress(), storeInfo.getAddress())) {
            if (StringUtils.isNotBlank(storeInfo.getAddress())) {
                needRiskControl = true;
                riskControlRequest.setShopAddress(storeInfo.getAddress());
            }
            updateRecord.setStoreAddress(storeInfo.getAddress());
        }
        if (!Objects.equals(dbRecord.getStorePhotos(), StringUtil.list2Str(storeInfo.getStorePhotos()))) {
            if (CollectionUtils.isNotEmpty(storeInfo.getStorePhotos())) {
                needRiskControl = true;
                riskControlRequest.setShopPictures(storeInfo.getStorePhotos());
            }
            updateRecord.setStorePhotos(StringUtil.list2Str(storeInfo.getStorePhotos()));
        }

        updateRecord.setStoreProvinceId(storeInfo.getProvinceId()).setStoreProvince(storeInfo.getProvinceName())
            .setStoreCityId(storeInfo.getCityId()).setStoreCity(storeInfo.getCityName())
            .setStoreCountryId(storeInfo.getCountryId()).setStoreCountry(storeInfo.getCountryName())
            .setIsPublicContact(userContactDTO.getIsPublicContact()).setIsRequireAttention(userContactDTO.getIsRequireAttention());
        return needRiskControl;
    }

    private UserStoreVO convertUserStoreVO(HeroUserContact heroUserContact) {
        if (heroUserContact == null) {
            return null;
        }
        UserStoreVO userStoreVO = new UserStoreVO();
        userStoreVO.setStoreName(heroUserContact.getStoreName());
        userStoreVO.setStorePhotos(StringUtil.str2List(heroUserContact.getStorePhotos()));
        return userStoreVO;
    }

    @Override
    public Long createHeroUserContact(HeroUserContact record){
        return userContactMapper.insertSelective(record);
    }

    @Override
    public boolean contactInfoIsPerfection(Long uid, HeroUserContact userContact) {
        if (Objects.isNull(uid) && Objects.isNull(userContact)) {
            throw new BusinessException(ExceptionMsgEnum.PARAM_ERROR);
        }
        if (Objects.isNull(userContact)) {
            userContact = this.getByUid(uid);
        }

        if (StringUtils.isBlank(userContact.getContactMobile())) {
            return false;
        }
        if (StringUtils.isBlank(userContact.getWechatNum())) {
            return false;
        }
        if (StringUtils.isBlank(userContact.getStoreProvince()) || StringUtils.isBlank(userContact.getStoreCity())) {
            return false;
        }

        return true;
    }
}